#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <vector>
#include <functional>
#include <sys/types.h>
#include <sys/wait.h>

//PrintBlock
void PrintBlock()
{
    sigset_t set,oset;
    sigemptyset(&set);
    sigemptyset(&oset);

    sigprocmask(SIG_BLOCK,&set,&oset);
    std::cout << "Block: "<< std::endl;

    for(int signo = 31; signo > 0; signo--)
    {
        if(sigismember(&oset,signo))
        {
            std::cout << 1;
        }
        else
        {
            std::cout << 0;
        }
    }
    std::cout << std::endl;

}
void PrintPending()
{
    sigset_t pending;
    ::sigpending(&pending);
    std::cout << "Pending: "<< std::endl;
    for(int signo = 31; signo > 0; signo--)
    {
        if(sigismember(&pending,signo))
        {
            std::cout << 1;
        }
        else
        {
            std::cout << 0;
        }
    }
    std::cout << std::endl;
}
void handler(int signo)
{
    static int cnt = 0;
    cnt++;
    while(true)
    {
        std::cout << "SIGNT : "<< signo << "  cnt: " <<" "<<getpid()<<" "<< cnt <<std::endl;
        PrintPending();
        sleep(1);
        break;
    }

}
int main()
{
    struct sigaction act,oact; 
    act.sa_handler = handler;
    sigemptyset(&act.sa_mask);
    sigaddset(&act.sa_mask,3);
    sigaddset(&act.sa_mask,4);
    sigaddset(&act.sa_mask,5);
    sigaddset(&act.sa_mask,6);
    ::sigaction(2,&act,&oact);

    while (true)
    {
        PrintPending();
        pause();
    }
    
    return 0;
}



// void PrintPending(const sigset_t &pending)
// {
//     std::cout<<"curr pending list["<<getpid()<<"]"<<std::endl;
//     for(int signo = 31; signo > 0; signo--)
//     {
//         if(sigismember(&pending,signo))
//         {
//             std::cout<<1;
//         }
//         else
//         {
//             std::cout<<0;
//         }
//     }
//     std::cout<<std::endl;
//     sleep(1);
// }
// void Handler(int signo)
// {
//     std::cout << "SIGNT : "<< signo << std::endl;
// }
// int main()
// {
//     ::signal(SIGINT,SIG_IGN);
//     //1. 对2号信号进行屏蔽
//     //栈上开辟的空间
//     sigset_t block,oblock;
//     sigemptyset(&block);
//     sigemptyset(&oblock);
//     //1.1 添加2号信号
//     //我们有没有把对二号信号的屏蔽，设置进入内核中？根本就没有，只是在用户栈上设置了block的位图结构
//     //并没有设置进入内核中
//     sigaddset(&block,2);
//     //1.2 设置进入内核中
//     sigprocmask(SIG_SETMASK,&block,&oblock);
//     int cnt = 0;
//     while (true)
//     {
//         // 2. 如何获取pending表呢？
//         sigset_t pending;
//         sigpending(&pending);
//         // 2.1打印
//         PrintPending(pending);
//         cnt++;
//         if(cnt == 6)
//         {
//             std::cout << "解除2号" << std::endl;
//             sigprocmask(SIG_UNBLOCK,&block,&oblock);
//         }
//     }
//     return 0;
// }


// int main()
// {
//     // ::signal(2,SIG_IGN); // ignore: 忽略
//     ::signal(2,SIG_DFL);//default：默认退出
//     while (true)
//     {
//         ::pause();
//     }
    
//     return 0;
// }

// int main()
// {
//     if(fork() == 0)
//     {
//         int a = 10;
//         a /= 0;

//         exit(0);
//     }
//     int status = 0;
//     waitpid(-1,&status,0);
//     printf("exit signal: %d, core dump: %d\n",status&0x7F,(status>>7)&1);
// }

// void Handler(int signo)
// {
//     std::cout << "SIGNT : "<< signo << std::endl;
// }
// int main()
// {
//     std::cout << "hello" << std::endl;

//     int a = 10;
//     a /= 0;
//     int *p = nullptr;
//     *p = 100;

//     while (true)
//     {}
//     return 0;
// }

// using func_t = std::function<void()>;
// int gcount = 0;
// std::vector<func_t> gfuncs;

// void hanlder(int signo)
// {
//     for(auto &f : gfuncs)
//     {
//         f();
//     }
//     std::cout << "gcount : " << gcount << std::endl;
//     alarm(1);
// }

// int main()
// {

//     gfuncs.push_back([]()
//                      { std::cout << "我是一个日志任务" << std::endl; });
//     gfuncs.push_back([]()
//                      { std::cout << "我是一个下载任务" << std::endl; });
//     gfuncs.push_back([]()
//                      { std::cout << "我是一个mysql任务" << std::endl; });
//     alarm(1); // 一次性的闹钟，超时alarm会自动被取消
//     signal(SIGALRM,hanlder);

//     for(;;)
//     {
//         ::pause();
//         std::cout << " Hi " << std::endl;
//         gcount++;
//     }
// }

// int number = 0;
// void die(int signumber)
// {
//     printf("get a sig : %d, count : %d\n",signumber,number);
// }
// int main()
// {
//     alarm(5);
//     sleep(2);
//     int n = alarm(0);
//     std::cout<<"n : "<<n<<std::endl;
//     // signal(SIGALRM,die);
//     // while (true)
//     // {
//     //     number++;
//     //     // printf("count: %d\n",number++);
//     // }

// }

// int main(int argc,char *argv[])
// {
//     int cnt = 5;
//     while (cnt)
//     {
//         std::cout << "hahaha alive"<<std::endl;
//         cnt--;
//         if(cnt<=0)
//             abort();
//     }

// }

// int main(int argc,char *argv[])
// {
//     int cnt = 5;
//     while (cnt)
//     {
//         std::cout << "hahaha alive"<<std::endl;
//         cnt--;
//         if(cnt<=0)
//             raise(9);
//     }
//    return 0;
// }

// void Usage(std::string proc)
// {
//     std::cout << "Usage: " << proc << " signumber processid " << std::endl;
// }
// int main(int argc,char *argv[])
// {
//     if(argc != 3)
//     {
//         Usage(argv[0]);
//         exit(1);
//     }

//     int signumber = std::stoi(argv[1]);
//     pid_t id = std::stoi(argv[2]);

//     int n = ::kill(id,signumber);
//     if(n < 0)
//     {
//         perror("kill");
//         exit(2);
//     }
//     exit(0);
// }

// void Handler(int signo)
// {
//     // 当对应的信号被触发，内核将会对应的信号编号，传递给自定义方法
//     std::cout << "SIGNT : "<< signo << std::endl;
// }
// int main()
// {
//     //signal怎么不放在循环里面？
//     //signal：如果没有产生2或者3号信号呢？
//     //捕捉信号
//     for(int signo = 1; signo < 32; signo++)
//     {
//         std::cout << "捕捉  " << signo << std::endl;
//         ::signal(signo,Handler); // 默认终止 -> 执行自定义方法 ： Handler
//     }
//     while(true)
//     {
//         sleep(1);
//         std::cout << "hehe" << std::endl;
//     }
//     return 0;
// }
